#pragma once
#include <iostream>
using namespace std;
#include <sys/select.h>
#include "mySock.hpp"
#include "myLog.hpp"
#define READ_EVE (0x1)
#define WRINTE_EVE (0x1 << 1)
#define EXCEPT_EVENT (0x1 << 2)
#define FD_SIZE (sizeof(fd_set) * 8)
static const uint16_t default_port = 8080;
static const int default_fd = -1;
static const uint8_t default_event = 0;

typedef struct FdEvent
{
    int fd_;
    uint8_t event_;
    uint16_t CilPort_;
    string CilIp_;
} type_t;
class SelectServer
{
public:
    // SelectServer()
    // {}
    SelectServer(uint16_t port = default_port)
        : port_(port)
    {
    }
    ~SelectServer()
    {
        listenSock_.Close();
    }
    void Init()
    {
        listenSock_.Socket();
        listenSock_.Bind(port_);
        listenSock_.Listen();
        fdArray_ = new type_t[FD_SIZE];
        if (fdArray_ == nullptr)
        {
            logMessge(FATAL, "申请数组失败！ 错误码：%d 错误原因：%s", errno, strerror(errno));
            exit(NEW_ERR);
        }
        for (int i = 0; i < FD_SIZE; i++)
        {
            fdArray_[i].fd_ = default_fd;
            fdArray_[i].event_ = default_event;
        }
    }
    void Accepter()
    {
        uint16_t CilentPort;
        string CilentIp;
        int sock = listenSock_.Accept(&CilentIp, &CilentPort);
        if (sock < 0)
        {
            logMessge(FATAL, "接受失败！ 错误码：%d 错误原因:%s", errno, strerror(errno));
            exit(ACCEPT_ERR);
        }

        int i = 1;
        for (; i < FD_SIZE; i++)
        {
            if (fdArray_[i].fd_ == default_fd)
                break;
        }
        if (i >= FD_SIZE)
        {
            logMessge(FATAL, "文件描述符达到上限！");
            exit(FD_FULL);
        }
        else
        {
            // logMessge(DEBUG,"接受成功！");
            fdArray_[i].fd_ = sock;
            fdArray_[i].CilIp_ = CilentIp;
            fdArray_[i].CilPort_ = CilentPort;
            fdArray_[i].event_ = READ_EVE;
        }
    }
    void Recv(int index)
    {
        // logMessge(DEBUG,"来到了Recv函数！");

        char buf[1024];
        int n = recv(fdArray_[index].fd_, buf, sizeof(buf) - 1, 0);
        if (n < 0)
        {
            close(fdArray_[index].fd_);
            logMessge(FATAL, "接受消息失败！ 错误码：%d 错误原因:%s", errno, strerror(errno));
        }
        else if (n == 0)
        {
            logMessge(INFO, "客户端已经关闭！需要对其处理");
            close(fdArray_[index].fd_);

            fdArray_[index].fd_ = default_fd;
            fdArray_[index].event_ = default_event;
        }
        else
        {
            buf[n - 1] = 0;
            cout << fdArray_[index].CilIp_ << ":" << fdArray_[index].CilPort_ << "## " << buf << endl;
            string echo = "[server echo]## ";
            send(fdArray_[index].fd_, echo.c_str(), echo.size(), 0);
        }
    }
    void Hander(fd_set &rset, fd_set &wset)
    {
        // logMessge(DEBUG,"来到了Hander函数！");
        for (int i = 0; i < FD_SIZE; i++)
        {
            if (fdArray_[i].fd_ == default_fd)
                continue;
            if ((fdArray_[i].event_ & READ_EVE) && (FD_ISSET(fdArray_[i].fd_, &rset)))
            {
                if (fdArray_[i].fd_ == listenSock_.Fd())
                {
                    // logMessge(DEBUG,"来了一个新连接！");
                    Accepter();
                }
                else if (fdArray_[i].fd_ != listenSock_.Fd())
                {
                    // logMessge(DEBUG,"读就绪，准备接收！");

                    Recv(i);
                }
                else
                {
                }
            }
            else if ((fdArray_[i].event_ & WRINTE_EVE) && (FD_ISSET(fdArray_[i].fd_, &wset)))
            {
            }
            else
            {
            }
        }
    }
    void Start()
    {
        fdArray_[0].fd_ = listenSock_.Fd();
        fdArray_[0].event_ = READ_EVE;

        while (1)
        {
            fd_set read_set;
            fd_set write_set;
            FD_ZERO(&read_set);
            FD_ZERO(&write_set);
            int maxFd = fdArray_[0].fd_;
            FD_SET(fdArray_[0].fd_, &read_set);

            for (int i = 1; i < FD_SIZE; i++)
            {

                if (fdArray_[i].fd_ == default_fd)
                {
                    continue;
                }
                if (fdArray_[i].event_ & READ_EVE)
                {
                    FD_SET(fdArray_[i].fd_, &read_set);
                    // logMessge(DEBUG,"设置读文件,i:%d",i);
                };
                if (fdArray_[i].event_ & WRINTE_EVE)
                {
                    FD_SET(fdArray_[i].fd_, &write_set);
                    // logMessge(DEBUG,"设置写文件");
                }
                if (maxFd < fdArray_[i].fd_)
                {
                    maxFd = fdArray_[i].fd_;
                    // logMessge(DEBUG,"更新最大文件描述符：%d，fdArray_[i].fd_: %d",maxFd,fdArray_[i].fd_);
                }
            }

            struct timeval timeout = {1, 0};

            int n = select(maxFd + 1, &read_set, &write_set, nullptr, nullptr);
            switch (n)
            {
            case -1: //
                break;
            case 0: // 超时返回
                break;
            default: // 一个事件就绪
                logMessge(INFO, "一个文件就绪！");
                Hander(read_set, write_set);
                Print();
            }
        }
    }
    void Print()
    {
        int count = 0;
        std::cout << "fdArray_[]: ";
        for (; count < FD_SIZE; count++)
        {
            if (fdArray_[count].fd_ == default_fd)
                continue;
            cout << fdArray_[count].fd_ << " ";
        }
        // while (fdArray_[count].fd_ != default_fd)
        // {
        //     cout << fdArray_[count].fd_ << " ";
        //     count++;
        // }
        cout << endl;
    }

private:
    uint16_t port_;
    Sock listenSock_;
    type_t *fdArray_;
};